﻿using Awsc.DataAcquisitionSys.Core.Common;
using Awsc.DataAcquisitionSys.Core.Databases;
using Awsc.DataAcquisitionSys.Core.Messages;
using Awsc.DataAcquisitionSys.Core.Models.POCO;
using Awsc.DataAcquisitionSys.Core.Repository;
using MediatR;

namespace Awsc.DataAcquisitionSys.Core.Services.MissionManagement
{
    public interface IMissionService
    {
        Task<IEnumerable<Mission>> GetAllMssionsAsync();
        Task<Mission> GetMissionAsync(int missionId);
        Task<bool> CreateMissionAsync(Mission mission);
        Task<bool> UpdateMissionAsync(int missionId, Mission mission);
        Task<bool> FinishMissionAsync(int missionId);
        Task<bool> ResumeMissionAsync(int missionId);
        Task<List<SensorDataRow>> GetMissionDataAsync(int missionId, DateTime startTime, DateTime endTime);
        Task<bool> StartMissionAsync(int missionId);

    }
    public class MissionService : IMissionService
    {
        private readonly IRepository<Mission> repository;
        private readonly SQLiteHelper dbHelper;
        private readonly IMediator mediator;

        public MissionService(IRepository<Mission> repository, SQLiteHelper dbHelper, IMediator mediator)
        {
            this.repository = repository;
            this.dbHelper = dbHelper;
            this.mediator = mediator;
        }

        public async Task<Mission> GetMissionAsync(int missionId)
        {
            return await repository.GetByIdAsync(missionId);
        }
        public async Task<bool> CreateMissionAsync(Mission mission)
        {
            ArgumentAssert.NotNull(mission);
            var result = await repository.AddAsync(mission);
            await StartMissionAsync(result.Id);
            return true;
        }
        public async Task<bool> UpdateMissionAsync(int missionId, Mission mission)
        {
            ArgumentAssert.GreaterThanZero(missionId);
            ArgumentAssert.NotNull(mission);
            var entity = await repository.GetByIdAsync(missionId);
            if (entity != null)
            {
                mission.Id = missionId;
                await repository.UpdateAsync(mission);
            }
            return true;
        }

        public async Task<bool> StartMissionAsync(int missionId)
        {
            ArgumentAssert.GreaterThanZero(missionId);
            var mission = await repository.GetByIdAsync(missionId);
            if (mission == null)
            {
                throw new ArgumentException($"Mission with ID {missionId} does not exist.");
            }
            mission.FinishTime = null;
            await repository.UpdateAsync(mission);
            await mediator.Publish(new MissionStartMessage(mission));

            //_missionDataWriter.StartRecording(mission);
            return true;
        }

        public async Task<bool> FinishMissionAsync(int missionId)
        {
            ArgumentAssert.GreaterThanZero(missionId);
            var mission = await repository.GetByIdAsync(missionId);
            mission.FinishTime = DateTime.UtcNow;
            await repository.UpdateAsync(mission);
            await mediator.Publish(new MissionStopMessage(mission));
            return true;
        }
        public async Task<bool> ResumeMissionAsync(int missionId)
        {
            await StartMissionAsync(missionId);
            return true;
        }


        public async Task<IEnumerable<Mission>> GetAllMssionsAsync()
        {
            return await repository.GetAllAsync();
        }

        public async Task<List<SensorDataRow>> GetMissionDataAsync(int missionId, DateTime startTime, DateTime endTime)
        {

            var mission = await GetMissionAsync(missionId);
            if (mission == null)
            {
                throw new ArgumentException("Mission not found");
            }
            var range = new List<SensorDataRow>();
            var sql = $"SELECT * FROM {mission.SensorDataTableName} WHERE MissionId = @MissionId AND 时间 BETWEEN @StartTime AND @EndTime";
            var rows = await dbHelper.QueryAsync(sql, new Dictionary<string, object>() { { "MissionId", missionId }, { "StartTime", startTime }, { "EndTime", endTime } });
            foreach (var row in rows)
            {
                var sensorDataRow = new SensorDataRow(row);
                sensorDataRow.Timestamp = DateTime.FromOADate((double)row["时间"]);
                range.Add(sensorDataRow);
            }
            return range;
        }


    }
}
